package com.snailhd.crawler;


import com.snailhd.common.util.HttpClientUtil;
import com.snailhd.dto.QueryStockListDTO;
import com.snailhd.entity.Stock;
import com.snailhd.entity.StockDay;
import com.snailhd.entity.StockRealTime;
import com.snailhd.entity.StockRealTimeBet;
import com.snailhd.listener.StockRealTimeListener;
import com.snailhd.mapper.StockMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 爬取股票实时数据
 * @author hd
 */

@Slf4j
@Component
public class CrawlerRealTimeStockDataExector {


    /**
     * 一次查询的条数
     */
    private final static int ONCE_CRAWL_STOCK_NUM = 100;

    /**
     * 匹配股票和股票数据
     */
    private final static Pattern STOCK_PATTERN = Pattern.compile("var hq_str_([\\w]*)=\"([^\"]*)\";");


    public List<StockRealTime> exec(String ... codes) throws Exception {
        List<StockRealTime> realTimes = new ArrayList<>(codes.length);
        UrlBuider urlBuider = new UrlBuider(codes);
        String url = null;
        while ((url =urlBuider.getUrl(ONCE_CRAWL_STOCK_NUM))!=null){
            log.info("----->{}",url);
            List<StockRealTime> list = craw(url);
            realTimes.addAll(list);
        }
        return realTimes;
    }


    private List<StockRealTime> craw(String url) throws Exception {
        try {
            String resultStr = HttpClientUtil.get("获取实时数据",url,null);
            Matcher m = STOCK_PATTERN.matcher(resultStr);
            List<StockRealTime> list = new ArrayList<>();
            while (m.find()){
                StockRealTime stockRealTime = buildStockRealTime(m.group(1),m.group(2).split(","));
                list.add(stockRealTime);
            }
            return list;
        }catch (Exception e){
            log.error("获取实时股票数据并存储异常：{}",url,e);
            throw e;
        }
    }

    private StockRealTime buildStockRealTime(String symbol,String[] es){

        StockRealTime s = new StockRealTime();
        s.setSymbol(symbol);
        s.setCode(symbol.substring(2));
        s.setTrade(new BigDecimal(es[3]));
        s.setAmount(new BigDecimal(es[9]));
        s.setHigh(new BigDecimal(es[4]));
        s.setLow(new BigDecimal(es[5]));
        s.setSettlement(new BigDecimal(es[2]));
        s.setOpen(new BigDecimal(es[1]));
        s.setVolume(new BigDecimal(es[8]));
        s.setDate(Integer.parseInt(es[30].replace("-","")));
        s.setTime(es[31]);
        s.setPricechange(s.getTrade().subtract(s.getSettlement()));
        s.setChangepercent(s.getPricechange().divide(s.getSettlement(),3).multiply(new BigDecimal(100)));

        s.saveBuyBet(new StockRealTimeBet(StockRealTimeBet.Level.ONE, new BigDecimal(es[10]), new BigDecimal(es[11])));
        s.saveBuyBet(new StockRealTimeBet(StockRealTimeBet.Level.TWO, new BigDecimal(es[12]), new BigDecimal(es[13])));
        s.saveBuyBet(new StockRealTimeBet(StockRealTimeBet.Level.THREE, new BigDecimal(es[14]), new BigDecimal(es[15])));
        s.saveBuyBet(new StockRealTimeBet(StockRealTimeBet.Level.FOUR, new BigDecimal(es[16]), new BigDecimal(es[17])));
        s.saveBuyBet(new StockRealTimeBet(StockRealTimeBet.Level.FIVE, new BigDecimal(es[18]), new BigDecimal(es[19])));

        s.saveSellBet(new StockRealTimeBet(StockRealTimeBet.Level.ONE, new BigDecimal(es[20]), new BigDecimal(es[21])));
        s.saveSellBet(new StockRealTimeBet(StockRealTimeBet.Level.TWO, new BigDecimal(es[22]), new BigDecimal(es[23])));
        s.saveSellBet(new StockRealTimeBet(StockRealTimeBet.Level.THREE, new BigDecimal(es[24]), new BigDecimal(es[25])));
        s.saveSellBet(new StockRealTimeBet(StockRealTimeBet.Level.FOUR, new BigDecimal(es[26]), new BigDecimal(es[27])));
        s.saveSellBet(new StockRealTimeBet(StockRealTimeBet.Level.FIVE, new BigDecimal(es[28]), new BigDecimal(es[29])));

        return s;
    }

}


class UrlBuider{

    private final static String URL = "http://hq.sinajs.cn/rn=1570713139313&list=";

    private String[] codes;
    private int index = 0;

    private String getUrl(){
        return getUrl(null);
    }

    public String getUrl(Integer max){
        if(max==null) {max = codes.length;}

        StringBuilder sb = new StringBuilder();

        for(int i=0;i<codes.length && i<=max && index<codes.length ;i++,index++){
            sb.append(",").append(codes[index]);
        }
        String str = sb.toString();
        if(StringUtils.isNotBlank(str)){
            return URL + str.substring(1);
        }else{
            return null;
        }
    }


    public UrlBuider(String[] codes) {
        this.codes = codes;
    }
}
